package com.larry.tinyweb.core;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Map;

/**
 * Created by larry on 16/9/20.
 * 请求实体
 */
public class RequestEntity {
    private HttpServletRequest request;
    private HttpServletResponse response;
    private Boolean isRouted = false;
    private Boolean isPlugin = true;
    private Boolean isStatic = false;

    private String routerName;
    private String methodName;
    private Map<String, Object> param;

    public RequestEntity(HttpServletRequest request, HttpServletResponse response) {
        this.request = request;
        this.response = response;
        make();
    }

    public static RequestEntity getEntity(HttpServletRequest request, HttpServletResponse response) {
        return new RequestEntity(request, response);
    }

    public boolean isStatic() {
        return isStatic;
    }

    /**
     * 设置该请求为静态资源请求
     */
    public void setStatic() {
        isStatic = true;
    }

    /**
     * 阻止接下来的插件
     */
    public void stopPlugin() {
        isPlugin = false;
    }

    public boolean canPlugin() {
        return isPlugin;
    }

    /**
     * 判断是否已经被路由
     * @return
     */
    public boolean hasRoute() {
        return isRouted;
    }

    /**
     * 设置为已经被路由
     */
    public void routed() {
        isRouted = true;
    }

    public String getMethodName() {
        return methodName;
    }

    public String getRouterName() {
        return routerName;
    }

    public HttpServletRequest getRequest() {
        return request;
    }

    public HttpServletResponse getResponse() {
        return response;
    }

    /**
     * 获取请求参数
     * @param key
     * @return
     */
    public String getParam(String key) {
        String[] vals = (String[]) param.get(key);
        if(vals.length == 0) {
            return null;
        } else if (vals.length == 1) {
            return vals[0];
        } else {
            String re = "";
            for (String s : vals) {
                re += "," + s;
            }
            return re.substring(1);
        }
    }

    /**
     * 解析路由名方法名以及参数
     */
    private void make() {
        String servletPath = request.getServletPath();
        if (servletPath.lastIndexOf("?") > -1 ) servletPath = servletPath.substring(0, servletPath.lastIndexOf("?"));
        if (servletPath.lastIndexOf(".") > -1) return;

        if (servletPath.endsWith("/")) servletPath = servletPath.substring(0, servletPath.lastIndexOf("/"));
        String[] ss = servletPath.split("/");

        Integer split = servletPath.lastIndexOf("/");
        //解析路由名
        routerName = servletPath.substring(0, split + 1);
        //解析方法名
        methodName = servletPath.substring(split + 1);

        //解析参数
        parseParam();
    }

    /**
     * 解析请求参数
     */
    private void parseParam() {
        String contentType = request.getContentType();
        if (contentType != null && contentType.indexOf("multipart/form-data") >= 0) {
            MultipartRequest multipartRequest = new MultipartRequest(request);
            multipartRequest.parse();
            this.param = multipartRequest.getParam();
        } else {
            // 普通请求
            this.param = request.getParameterMap();
        }
    }

    /**
     * 服务器内部跳转
     * @param path
     */
    public void forward(String path) {
        try {
            request.getRequestDispatcher(path).forward(request, response);
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 客户端跳转
     * @param path
     */
    public void redirect(String path) {
        try {
            if (path.startsWith("/")) path = Global.contextPath + path;
            response.sendRedirect(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 向客户端返回普通的字符串
     * @param str
     */
    public void writeString(String str) {
        try {
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(str.getBytes());
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void setAttr(String key, Object val) {
        request.setAttribute(key, val);
    }

    public void session() {

        request.getSession().setAttribute("ID", request.getSession().getId());
    }
    public void unsession() {
        request.getSession().invalidate();
    }

    public void login() {
        redirect(Global.loginPath);
        routed();
    }

    public void go404() {
        forward("/front/inc/404.jsp");
    }

    public void go500() {
        forward("/front/inc/500.jsp");
    }
}
